/*
    原作者地址：  http://www.cnblogs.com/lianmin/p/4625835.html
    自己只是参照他的学习了一下而已，具体去看原文吧;
*/


//缓动函数
jQuery.easing["jswing"] = jQuery.easing["swing"];
jQuery.extend(jQuery.easing, {
    def: "easeOutQuad",
    swing: function (x, t, b, c, d) {
        return jQuery.easing[jQuery.easing.def](x, t, b, c, d)
    },
    easeOutQuad: function (x, t, b, c, d) {
        return -c * (t /= d) * (t - 2) + b
    },
    easeOutBounce: function (x, t, b, c, d) {
        if ((t /= d) < (1 / 2.75)) {
            return c * (7.5625 * t * t) + b
        } else {
            if (t < (2 / 2.75)) {
                return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b
            } else {
                if (t < (2.5 / 2.75)) {
                    return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b
                } else {
                    return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b
                }
            }
        }
    }
});

/*
    扩展 string.format
    传入几个参数，依次替换字符串中相匹配的；
*/
String.prototype.format = function () {
    var args = arguments;
    var reg = /\{(\d+)\}/g;
    return this.replace(reg, function (g0, g1) {
        return args[+g1];
    })
};
// test
// var a = '啊{0}飒{0}飒{1}飒{2}飒{0}是'
// console.log(a.format('c','r','asas'));

/*jq 队列封装*/
(function ($) {
    $.fn.will = function (callback, type) {
        type = type || 'fx';
        return $.each(this, function (index, ele) {
            $(ele).queue(type, function (next) {
                callback.call(this);
                next();
            })
        })
    }
})(jQuery);

/*banner 封装*/
(function ($) {

    function Slider(option) {
        this.opt = $.extend(true, {}, option);
        this.ele = $('#' + this.opt.id);

        this.init();    //初始化
        this.begin();   //开始轮播
    }
    Slider.prototype = {
        cubeSize: {
            x: 0,
            y: 0
        }, //每一个格子的尺寸
        nowIndex: 0, //当前图片索引
        canChose: true, //是否可以切换
        nextIndex: function () { //下一个图片索引
            var newIndex = this.nowIndex + 1;
            if (newIndex >= this.opt.imgs.length) newIndex = 0;
            return newIndex;
        },
        prevIndex: function () { //上一张图片索引
            var newIndex = this.nowIndex - 1;
            if (newIndex < 0) newIndex = this.opt.imgs.length-1;
            return newIndex;
        },
        init: function () { //初始化
            this.preLoad();
            this.fill();
            this.resize();
            var self = this;
            $(window).resize(function () {
                self.resize();
            });
        },
        preLoad:function(){ //预加载图片
            var arr = this.opt.imgs;
            $.each(arr,function(index,url){
                var img = new Image();
                img.src = url;
            })
        },
        begin:function(){   //开始轮播
            var self = this;
            this.timer = setInterval(function(){
                var newIndex = self.nowIndex + 1;
                if (newIndex >= self.opt.imgs.length) newIndex = 0;
                self.choseImg(newIndex);
            },self.opt.interval);
        },
        stop:function(){    //停止转动轮播；
            clearInterval(this.timer);
        },
        fill:function(){   //填充banner拨快
           var result = '<div class="slider-box">';
           //插入格子
           for(var x = 0; x<this.opt.x; x++){
               for(var y= 0; y<this.opt.y; y++){
                   result +='<div id="{0}" class="{1}"><div class="slider_inner_a"></div><div class="slider_inner_b"></div></div>'
                            .format(this.opt.id + '_' + x + '_' + y,'slider_cube');
               }
           }
           
           //如果需要分页器，则插入slider_bar;
           if(this.opt.showBar){
                result += '<div class="slider_bar">';
                result += new Array(this.opt.imgs.length + 1).join('<span></span>');
                result += '</div>';
           }

           result+='</div>';
           //插入页面
           this.ele.html(result);
           this.ele.find('.slider_bar span').eq(this.nowIndex).addClass('active');
           this.eleBox = this.ele.children('.slider-box');

           //绑定事件
           this.bindEvents();
        },
        bindEvents:function(){    //绑定点击事件
            var self = this;

            //绑定分页器点击事件
            if(this.opt.showBar){
                this.eleBox.children('.slider_bar').off().on('click','span',function(){
                    self.choseImg($(this).index());
                })
            }
            // mouseenter停止mouseleave开始
            self.eleBox.mouseenter(function(){
                self.stop();
            }).mouseleave(function() {
                self.begin();
            });

            //如果有跳转连接，点击图片跳转,
            if(this.opt.urls.length <=0) return;
            self.eleBox.find('.slider_cube').off('click').on('click',function(){
                window.location.href = self.opt.urls[self.nowIndex] || 'javascript:void(0);';
            }).css('cursor','pointer');
        },
        resize:function(){  //改变大小，位置
            var self = this;
            this.eleBox.height(this.eleBox.width() / this.opt.scale);

            var eleW = this.eleBox.width(),
                eleH = this.eleBox.height();

            var xSize,ySize; //每一块的size

            //计算单元格大小
            if(this.opt.border){    //如果显示间隔
               xSize = (eleW - this.opt.x+1) / this.opt.x;
               ySize = (eleH - this.opt.y+1) / this.opt.y;
            }else{
                xSize = eleW / this.opt.x;
                ySize = eleH / this.opt.y;
            }
            this.cubeSize = { x: xSize, y: ySize };

            //计算position,位置
            var borLen = this.opt.border ? 1 : 0;
            for(var x = 0; x<this.opt.x; x++){
                for(var y = 0; y<this.opt.y; y++){
                    $('#' + this.opt.id + '_' + x + '_' + y).css({
                        'left': x * xSize + x * borLen + 'px',
                        'top': y * ySize + y * borLen + 'px',
                        'width': xSize + 'px',
                        'height': ySize + 'px'
                    }).find('.slider_inner_a,.slider_inner_b').css({
                        'background-image':'url({0})'.format(self.opt.imgs[self.nowIndex]),
                        'background-position':'{0}px {1}px'.format(-x * xSize + borLen, -y * ySize + borLen),
                        'background-size':'{0}px {1}px'.format(eleW, eleH)
                    });
                }
            }
            //..
        },
        choseImg:function(index){
            var self = this;

            if(index === self.nowIndex) return; //如果图片没变

            if(!self.canChose) return ;//是否可以切换
            self.canChose = false;
            setTimeout(function(){
                self.canChose = true;
            },self.opt.delay + 200);

            this.nowIndex = index;
            var url = this.opt.imgs[index];
            //效果序号
            this.effectIndex = this.effectIndex || 0;
            if(this.effectIndex >=this.effects.length) this.effectIndex = 0;
            //效果
            this.effects[this.effectIndex](this, url);  
            this.effectIndex++;

            //分页器 active效果
            if(self.opt.showBar){
                self.eleBox.children('.slider_bar').find('span').removeClass('active').eq(self.nowIndex).addClass('active');
            }
        },
        effects:[   //效果列表
            function (self, url) {  //百叶窗从左到右
                var delayItem = self.opt.delay / self.opt.x;
                effectTemplate(self.opt, function (eleA, eleB, x, y) {
                    eleA.css({
                        'left': -self.cubeSize.x + 'px',
                        'background-image': 'url({0})'.format(url)
                    });
                    var delayTime = x * delayItem;
                    eleA.delay(delayTime).animate({
                        'left': '0'
                    }, {
                        duration: delayItem * 3
                    });
                    eleB.delay(delayTime).animate({
                        'left': self.cubeSize.x + 'px'
                    }, {
                        duration: delayItem * 3
                    }).will(function () {
                        $(this).css({
                            'left': '0',
                            'background-image': 'url({0})'.format(url)
                        });
                    });
                });
            },
            function (self, url) {   //落下效果
                var delayItem = self.opt.delay / (self.opt.x * self.opt.y);
                effectTemplate(self.opt,function(eleA, eleB, x, y){
                    eleA.css({
                        'top':-self.cubeSize.y +'px',
                        'background-image':'url({0})'.format(url)
                    });

                    var delayTime = (x + (self.opt.x * y)) * delayItem;
                    eleA.delay(delayTime).animate({
                        'top':'0'
                    }, {
                       duration: delayItem * 15,
                       easing :'easeOutBounce'
                    });

                    eleB.delay(delayTime).animate({
                        'top':self.cubeSize.y + 'px'
                    },{
                       duration: delayItem * 15,
                       easing :'easeOutBounce'
                    }).will(function () {
                        $(this).css({
                            'top': '0',
                            'background-image': 'url({0})'.format(url)
                        });
                    });
                })
            },
            function (self, url) {  //依次渐入
                var delayItem = self.opt.delay / (self.opt.x * self.opt.y);
                effectTemplate(self.opt, function (eleA, eleB, x, y) {
                    eleA.css({
                        'opacity': '0',
                        'background-image': 'url({0})'.format(url)
                    });
                    var delayTime = (x + (y * self.opt.x)) * delayItem;
                    eleA.delay(delayTime).animate({
                        'opacity': '1'
                    }, {
                        duration: delayItem * 3
                    });
                    eleB.delay(delayTime).animate({
                        'opacity': '0'
                    }, {
                        duration: delayItem * 3
                    }).will(function () {
                        $(this).css({
                            'opacity': '1',
                            'background-image': 'url({0})'.format(url)
                        });
                    });
                });
            },
            function (self, url) {    //乱序随机滑动
                //生成随机延迟时间
                var delayArr = [0];
                var delayItem = self.opt.delay / (self.opt.x * self.opt.y);
                for (var i = 1, len = self.opt.x * self.opt.y; i < len; i++){
                    delayArr[i] = delayArr[i - 1] + delayItem
                };
                //随机排序
                delayArr.sort(function (a, b) {
                    return Math.random() > 0.5 ? 1 : -1;
                });

                effectTemplate(self.opt, function (eleA, eleB, x, y) {
                    //随机方向
                    var directionIndex = Math.floor(Math.random() * 4); //0-上，1-右，2-下，3-左
                    var cssName = ["top", "left", "top", "left"][directionIndex]; //属性名称
                    var cssValue = [-self.cubeSize.y, self.cubeSize.x, self.cubeSize.y, -self.cubeSize.x][directionIndex];//模块一的起始值，模块二的终止值取反

                    var obj = {};
                    obj[cssName] = cssValue + "px";
                    obj["background-image"] = "url({0})".format(url);
                    eleA.css(obj);

                    var delayTime = delayArr[x + y * self.opt.x];
                    obj = {};
                    obj[cssName] = "0";
                    eleA.delay(delayTime * 3 / 4).animate(obj, delayItem * 4);

                    obj = {};
                    obj[cssName] = -cssValue + "px";
                    eleB.delay(delayTime * 3 / 4).animate(obj, delayItem * 4).will(function () {
                        obj = {};
                        obj[cssName] = "0";
                        obj["background-image"] = "url({0})".format(url);
                        $(this).css(obj);
                    });
                });
            }
        ]
    }

    /*动画模板辅助方法*/
    function effectTemplate(opt,callback){
        for(var y = 0; y < opt.y; y++){
            for(var x = 0; x < opt.x; x++){
                var eleBox = $('#{0}_{1}_{2}'.format(opt.id,x,y));
                var eleA = eleBox.children('.slider_inner_a');
                var eleB = eleBox.children('.slider_inner_b');
                callback(eleA,eleB,x,y);
            }
        }
    }

    //随机id
    function getRandomId(){
        return Math.random().toString(36).substr(2).replace(/\d/g,'');
    }

    /*jq扩展slider方法*/
    $.fn.slider = function (option, obj){
        //传入一个obj初始化
        if(typeof option == 'object'){
            var defaults = { //默认配置
                imgs: [],       //图片路径数组
                urls: [],         //点击跳转到的链接
                x: 2,          //横向模块数量
                y: 2,          //纵向模块数量
                scale: 4 / 3,      //宽高比
                delay: 800,        //动画时长
                interval: 5000,  //自动播放间隔
                border: false   //显示模块间隔
            };

            //jQuery对象是一个伪数组对象，可能有多个元素
            return $.each(this, function (index, ele) {
                // code...

                //最终配置
                var opt = $.extend({}, defaults, option);

                if (!ele.id) {    //给个id，方便方块命名
                    ele.id = getRandomId();
                }
                opt.id = ele.id;

                var slider = new Slider(opt);
                $(ele).data('slider', slider);
            });
        //传入一个字符串重新赋值
        }else if(typeof option === 'string') {
            var slider = this.data('slider');
            slider.opt = $.extend({}, slider.opt, obj || {});
            slider.init();
            slider.stop();
            slider.begin();
            if (typeof obj === 'object'){
                slider[option]()
            }else{
                slider[option](obj);
            }
            return this;
        } else {
            return this;
        }
    }
})(jQuery);